package com.ju.demo.service.impl;

import com.ju.demo.bo.ExchangeTeamInfo;
import com.ju.demo.bo.teamInfo.*;
import com.ju.demo.constant.ResultCodeConstant;
import com.ju.demo.dto.ExchangeTeamDTO;
import com.ju.demo.dto.teamDTOInfo.BuildMsgDTO;
import com.ju.demo.dto.teamDTOInfo.ToolmeterMsgDTO;
import com.ju.demo.entity.*;
import com.ju.demo.service.*;
import com.ju.demo.util.LogUtil;
import com.ju.demo.util.RandomCountUtil;
import com.mongodb.client.result.DeleteResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service
public class ExchangeTeamServiceImpl2 implements ExchangeTeamService2 {

    @Autowired
    private ClienteleService clienteleService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private MonitorService monitorService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ImageService imageService;

    /**
     * 通过日期查询到当天所有的交换班信息
     * @param date  日期
     * @return  当天所有的交换班信息
     * Document 是一个用于表示MongoDB文档的类,是MongoDB Java驱动程序提供的一种特定于Java的类型。
     *
     */
    @Override
    public List<ExchangeTeam> findTeamsByTime(String date) {

        // 创建查询条件
        Criteria criteria = Criteria.where("time").is(date);

        // 构建查询对象
        Query query = new Query(criteria);
        query.with(Sort.by(Sort.Direction.ASC,"id"));   //根据id进行升序-排序

        //执行查询
        List<ExchangeTeam> results = mongoTemplate.find(query, ExchangeTeam.class,"exchangeteam");

//        for (ExchangeTeam result : results) {
//            LogUtil.write(result.toString());
//        }
        return results;
    }

    /**
     * 通过具体的交换班id，查询到具体的交换班信息
     * @param id    前端传来的交换班id
     *
     * 参数id，就是数据库中各个team实例的id
     * 通过id，可以查询到点击的team交换班详情
     * id 唯一
     */
    @Override
    public ExchangeTeamInfo findTeamByID(Integer id,String date) {

        //1.构建查询对象并设置查询条件
        //1.1 通过前端传来的id值，也就是对应counters表中的sequenceValue值
        // 使用sequenceValue值查询到对应的documentId,documentId就是team表中的_id
        Query CountersQuery = new Query(Criteria.where("sequenceValue").is(id.toString()));
        LogUtil.write("查询条件："+CountersQuery.toString());

        Counter counterTemp = mongoTemplate.findOne(CountersQuery, Counter.class, "counters");

        LogUtil.write("查询counters：" + counterTemp);
        String documentId = counterTemp.getDocumentId();

        ExchangeTeam team = mongoTemplate.findById(documentId, ExchangeTeam.class,"exchangeteam");

        LogUtil.write(team.toString());

        //获取交换班人员信息
        TeamID teamID = team.getTeamID();
        String beforeTeamID = teamID.getBeforeTeamID();
        String currentTeamID = teamID.getCurrentTeamID();
        String clienteleID = teamID.getClienteleID();

        //team
        //mybatis-plus查询交换班人员信息     monitor--班长     members--班组成员    clientele--客户
        //1.交换班 当班 信息
        List<Member> currentMembers = memberService.findMembersByTeamID(Integer.valueOf(currentTeamID));
        Monitor currentMonitor = monitorService.findMonitorByTeamID(Integer.valueOf(currentTeamID));
        //2.交换班 前班 信息
        List<Member> beforeMembers = memberService.findMembersByTeamID(Integer.valueOf(beforeTeamID));
        Monitor beforeMonitor = monitorService.findMonitorByTeamID(Integer.valueOf(beforeTeamID));
        //3.封装
        Team teamInfo = new Team(currentMonitor, currentMembers, beforeMonitor, beforeMembers);
        //clientele
        Clientele clientele = clienteleService.findClienteleByID(Integer.valueOf(clienteleID));

        //teamMsg
        TeamMsg teamMsg = team.getTeamMsg();

        //toolmeterMsg
        ToolmeterMsg toolmeterMsgTemp = team.getToolmeterMsg();

        //equipmentTroubleMsg
        EquipmentTroubleMsg equipmentTroubleMsg = team.getEquipmentTroubleMsg();
        String equipmentTroubleMsgFlow = equipmentTroubleMsg.getFlow();
        String equipmentTroubleMsgMsg = equipmentTroubleMsg.getMsg();
        EquipmentTroubleMsg equipmentTroubleMsgTemp = new EquipmentTroubleMsg(equipmentTroubleMsgFlow,equipmentTroubleMsgMsg);

        //equipmentChangeMsg
        EquipmentChangeMsg equipmentChangeMsg = team.getEquipmentChangeMsg();
        String equipmentChangeMsgFlow = equipmentChangeMsg.getFlow();
        String equipmentChangeMsgMsg = equipmentChangeMsg.getMsg();
        EquipmentChangeMsg equipmentChangeMsgTemp = new EquipmentChangeMsg(equipmentChangeMsgFlow,equipmentChangeMsgMsg);

        //equipmentRunMsg
        String equipmentRunMsgTemp = team.getEquipmentRunMsg();

        //equipmentOperationMsg
        String equipmentOperationMsgTemp = team.getEquipmentOperationMsg();

        //buildMsg
        BuildMsg buildMsg = team.getBuildMsg();
        String buildMsgMsg = buildMsg.getMsg();
        String buildMsgPhotoMsg = buildMsg.getPhotoMsg();
        BuildMsg buildMsgTemp = new BuildMsg(buildMsgMsg,buildMsgPhotoMsg);

        //将数据封装，上传
        ExchangeTeamInfo exchangeTeamInfo = new ExchangeTeamInfo(date,teamMsg,teamInfo,clientele,toolmeterMsgTemp,
                equipmentOperationMsgTemp,equipmentTroubleMsgTemp,equipmentChangeMsgTemp,equipmentRunMsgTemp,buildMsgTemp);

        LogUtil.write("exchangeTeamInfo:" + exchangeTeamInfo.toString());

        return exchangeTeamInfo;

    }

    /**
     * 添加交换班
     * @return
     *
     * 从exchangeTeamInfo中解析出TeamID，然后封装成exchangeTeam进行存储
     * 暂时不考虑流转
     */
    @Override
    public ResultCodeConstant addExchangeTeam(ExchangeTeamDTO exchangeTeamInfo) {


        //初始化ExchangeTeam 和 counter
        ExchangeTeam exchangeTeam = new ExchangeTeam();
        Counter counter = new Counter();

        //使用BeanUtils的属性复制
        BeanUtils.copyProperties(exchangeTeamInfo,exchangeTeam);

        //teamID
        //获取team ID用来封装到ExchangeTeam中
        Team team = exchangeTeamInfo.getTeam();
        Integer beforeTeamId = team.getBeforeMonitor().getTeamId();
        Integer currentTeamId = team.getCurrentMonitor().getTeamId();
        String clienteleId = exchangeTeamInfo.getClientele().getClienteleId();
        TeamID teamID = new TeamID(currentTeamId.toString(), beforeTeamId.toString(), clienteleId);
        exchangeTeam.setTeamID(teamID);

        //图片处理
        //两个需要处理的变量，buildmsg 和 toolmetermsg
        //1.先获取图片，然后将图片转码成string
        BuildMsgDTO buildMsg = exchangeTeamInfo.getBuildMsg();
        ToolmeterMsgDTO toolmeterMsg = exchangeTeamInfo.getToolmeterMsg();
        //1.1获取图片对象
        MultipartFile buildMsgphotoMsg = buildMsg.getPhotoMsg();
        MultipartFile toolmeterMsgPhotoMsg = toolmeterMsg.getPhotoMsg();
        //1.2转码
        String saveImage = imageService.saveImage(buildMsgphotoMsg);
        String saveImage1 = imageService.saveImage(toolmeterMsgPhotoMsg);
        //2.保存
        exchangeTeam.setBuildMsg(new BuildMsg(buildMsg.getMsg(),saveImage));
        exchangeTeam.setToolmeterMsg(new ToolmeterMsg(toolmeterMsg.getErrorMsg(),saveImage1));


        /**
         * 设置id  主键
         * 创建一个随机数，将此随机数作为两张表的关联字段。
         *  通过随机数可以从另一张表查到team文档的id
         */

        //1.创建随机数
        String randomNumber = RandomCountUtil.getRandomNumber();
        //2. 关联两张表
        //2.1 设置team表 和 counters 中需要关联的字段
        //2.1.1 查重！ -->查询两张表里是否已经存在 意外相同的randomNumber的值
        // 查重：待实现
        exchangeTeam.setId(randomNumber);
        counter.setDocumentId(randomNumber);
        //2.2 设置counters表 & 查询并更新计数器
        //2.2.1 查询出counters表中最后的一个sequenceValue值
        Query query = new Query().with(Sort.by(Sort.Direction.DESC,"sequenceValue")).limit(1);
        Counter counters = mongoTemplate.findOne(query, Counter.class, "counters");
        //2.2.2 计算出最新的sequenceValue值，并且设置 +1
        Integer intVar = Integer.parseInt(counters.getSequenceValue()) + 1;
        String newSequenceValue = intVar.toString();
        //2.3 在counters设置 team表的id字段
        counter.setSequenceValue(newSequenceValue);



        LogUtil.write("即将保存的数据：" + exchangeTeam);

        //根据集合名保存数据
        ExchangeTeam save = mongoTemplate.save(exchangeTeam,"exchangeteam");
        //保存 counters 表
        Counter result = mongoTemplate.save(counter, "counters");

        if (save==null || result == null){
            return  ResultCodeConstant.SAVE_EXCHANGE_TEAM_FAIL;
        }

        LogUtil.write("保存的数据：" + save);
        return ResultCodeConstant.SUCCESS;
    }

    /**
     * 删除交换班
     * 删除交换班信息的同时，也删除计数器集合counters表中对应的数据
     * 先查找到交换班信息，删除交换班然后删除计数器对应的信息
     */
    @Override
    public ResultCodeConstant deleteExchangeTeam(Integer id) {
        //通过id查询 准备删除的文档数据
        //1.构建查询对象并设置查询条件
        //1.1 通过前端传来的id值，也就是对应counters表中的sequenceValue值
        // 使用sequenceValue值查询到对应的documentId,documentId就是team表中的_id
        Query CountersQuery = new Query(Criteria.where("sequenceValue").is(id.toString()));

        Counter counterTemp = mongoTemplate.findOne(CountersQuery, Counter.class, "counters");
        LogUtil.write("查询counters：" + counterTemp);

        //查找team对应的id
        String documentId = counterTemp.getDocumentId();
        LogUtil.write("查询teamId:" + documentId);

        //删除team和counter
        Query query = new Query(Criteria.where("_id").is(documentId));
        DeleteResult removeResult = mongoTemplate.remove(query, ExchangeTeam.class, "exchangeteam");
        DeleteResult removeCounters = mongoTemplate.remove(CountersQuery, Counter.class, "counters");

        LogUtil.write("成功删除交换班信息：" + removeResult);
        LogUtil.write("成功删除计数器信息：" + removeCounters);

        if (removeResult.getDeletedCount() == 0){
            return ResultCodeConstant.REMOVE_EXCHANGE_TEAM_FAIL;
        }
        return ResultCodeConstant.SUCCESS;
    }

    /**
     * 修改交换班信息
     * 页面的顺序 与 counters 表中的sequenceValue对应。
     * 通过sequenceValue查询到exchangeteam中需要修改的文档
     * 将前端传来的表单数据映射到实体类，根据交换班的id进行覆盖
     * @return
     */
    @Override
    public ResultCodeConstant updateExchangeTeam(Integer id,ExchangeTeamDTO exchangeTeamInfo) {

        //1.构建查询对象并设置查询条件
        //1.1 通过前端传来的id值，也就是对应counters表中的sequenceValue值
        // 使用sequenceValue值查询到对应的documentId,documentId就是team表中的_id
        Query CountersQuery = new Query(Criteria.where("sequenceValue").is(id.toString()));
        LogUtil.write("查询条件："+CountersQuery.toString());

        Counter counterTemp = mongoTemplate.findOne(CountersQuery, Counter.class, "counters");

        LogUtil.write("查询counters：" + counterTemp);
        String documentId = counterTemp.getDocumentId();

        //1.2 查询team条件
        Query query = new Query(Criteria.where("_id").is(documentId));

        //2.查询到需要修改的文档
//        ExchangeTeam exchangeTeam = mongoTemplate.findById(id, ExchangeTeam.class);
        ExchangeTeam exchangeTeam = mongoTemplate.findOne(query, ExchangeTeam.class, "exchangeteam");
        LogUtil.write("即将修改的文档：" + exchangeTeam);

        if (exchangeTeam == null){
            //无法查询到对应id的数据
            return ResultCodeConstant.UPDATE_EXCHANGE_TEAM_FINDINFO_BYID_FAIL;
        }

        //3.将基本属性进行覆盖 除了id(不可覆盖)和teamID
        // buildMsg 和 toolMeterMsg 因为图片属性需要手动覆盖
        BeanUtils.copyProperties(exchangeTeamInfo,exchangeTeam);

        //3.1覆盖team ID
        String clienteleId = exchangeTeamInfo.getClientele().getClienteleId();
        Team team = exchangeTeamInfo.getTeam();
        String currentTeamId = team.getCurrentMonitor().getTeamId().toString();
        String beforeTeamId = team.getBeforeMonitor().getTeamId().toString();
        exchangeTeam.setTeamID(new TeamID(currentTeamId,beforeTeamId,clienteleId));

        //3.2 覆盖buildMsg 和 toolMeterMsg

        //3.2.1 先获取图片，然后将图片转码成string
        BuildMsgDTO buildMsg = exchangeTeamInfo.getBuildMsg();
        ToolmeterMsgDTO toolmeterMsg = exchangeTeamInfo.getToolmeterMsg();
        //3.2.2获取图片对象
        MultipartFile buildMsgphotoMsg = buildMsg.getPhotoMsg();
        MultipartFile toolmeterMsgPhotoMsg = toolmeterMsg.getPhotoMsg();
        //3.2.3 转码
        String saveImage = imageService.saveImage(buildMsgphotoMsg);
        String saveImage1 = imageService.saveImage(toolmeterMsgPhotoMsg);
        //3.2.4 保存
        exchangeTeam.setBuildMsg(new BuildMsg(buildMsg.getMsg(),saveImage));
        exchangeTeam.setToolmeterMsg(new ToolmeterMsg(toolmeterMsg.getErrorMsg(),saveImage1));



        //4.覆盖完成  进行保存
        ExchangeTeam result = mongoTemplate.save(exchangeTeam, "exchangeteam");
        if (result == null){
            //保存失败
            return ResultCodeConstant.UPDATE_EXCHANGE_TEAM_FAIL;
        }

        LogUtil.write("修改结果：" + ResultCodeConstant.SUCCESS);
        return ResultCodeConstant.SUCCESS;
    }
}
